package com.szis.auth.runner;

import com.alibaba.fastjson2.JSON;
import com.szis.auth.common.ServerManager;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.List;

/**
 * @author: yxl
 * 2025-07-17
 */

@Component
@Slf4j
@Order(2)
public class ServerStartUp implements CommandLineRunner {

    @Value("${spring.application.name}")
    private String appName;

    @Value("${server.port}")
    private Integer port;

    @Resource
    private ServerManager serverManager;

    @Override
    public void run(String... args) {
        // 获取appName服务节点信息
        List<ServerManager.ServerNodeInfo> servers = serverManager.listServers(appName);
        if (CollectionUtils.isNotEmpty(servers)) {
            servers.forEach(server -> {
                // 服务是否存活检查
                if (!telnet(server, 2000)) {
                    serverManager.unregister(server);
                }
            });
        }

        long count = servers.stream().filter(server->server.getHost().equals(localIPAddress()) && server.getPort().equals(port)).count();
        ServerManager.ServerNodeInfo server = new ServerManager.ServerNodeInfo(appName, localIPAddress(), port);
        serverManager.set(server);
        if (CollectionUtils.isEmpty(servers) || count == 0) {
            serverManager.register(server);
        }
        servers = serverManager.listServers(appName);
        log.info("服务 {} 节点数量: {} 节点信息: {} ", appName, servers.size(), JSON.toJSONString(servers));
        log.info("workerId: {}", serverManager.workerId(appName, new ServerManager.ServerNodeInfo(appName, localIPAddress(), port)));
    }

    /**
     * 获取本机IP地址
     *
     * @return IP 地址
     */
    private String localIPAddress() {
        try {
            InetAddress localHost = InetAddress.getLocalHost();
            return localHost.getHostAddress();
        } catch (UnknownHostException e) {
            log.error(e.getMessage(), e);
            throw new RuntimeException("获取本机IP地址失败");
        }
    }

    /**
     * 检查指定 IP 和端口是否可连接
     *
     * @param server  服务节点信息
     * @param timeout 超时时间（毫秒）
     * @return 是否可连接
     */
    private static boolean telnet(ServerManager.ServerNodeInfo server, int timeout) {
        try (Socket socket = new Socket()) {
            socket.connect(new InetSocketAddress(server.getHost(), server.getPort()), timeout);
            return true;
        } catch (IOException e) {
            return false;
        }
    }

}
